//
//  NSAttributedString+Lc.m
//  18Birdies
//
//  Created by Lc on 15/4/5.
//  Copyright (c) 2015年 Lc. All rights reserved.
//

#import "LcFont.h"
#import "NSAttributedString+Lc.h"
#import "LcFoundation.h"

@implementation NSAttributedString (Lc)

+ (NSAttributedString*)attributedStringWithString:(NSString*)string
                                           lcFont:(LcFont*)lcFont {
  if (string.length == 0) {
    return [[NSAttributedString alloc] init];
  }
  //  NSMutableParagraphStyle* paragraphStyle =
  //      [[NSMutableParagraphStyle alloc] init];
  //  paragraphStyle.headIndent = 0;
  //  paragraphStyle.firstLineHeadIndent = 0;
  NSAttributedString* attributedString = [[self alloc]
      initWithString:string
          attributes:@{
            NSFontAttributeName : lcFont.font,
            NSForegroundColorAttributeName : lcFont.color,
            //                          NSParagraphStyleAttributeName :
            //                          paragraphStyle,
          }];
  return attributedString;
}

+ (NSAttributedString*)underlineStringWithString:(NSString*)string
                                          lcFont:(LcFont*)lcFont {
  if (string.length == 0) {
    return [[NSAttributedString alloc] init];
  }
  NSAttributedString* attributedString = [[self alloc]
      initWithString:string
          attributes:@{
            NSFontAttributeName : lcFont.font,
            NSForegroundColorAttributeName : lcFont.color,
            NSUnderlineStyleAttributeName : @(NSUnderlineStyleSingle),
          }];
  return attributedString;
}

+ (NSAttributedString*)obliquenessStringWithString:(NSString*)string
                                            lcFont:(LcFont*)lcFont {
  if (string.length == 0) {
    return [[NSAttributedString alloc] init];
  }
  NSAttributedString* attributedString =
      [[self alloc] initWithString:string
                        attributes:@{
                          NSFontAttributeName : lcFont.font,
                          NSForegroundColorAttributeName : lcFont.color,
                          NSObliquenessAttributeName : @(0.2),
                        }];
  return attributedString;
}

+ (NSMutableAttributedString*)attributedStringWithBoldTagString:
                                  (NSString*)boldTagString
                                                    regularFont:(LcFont*)font {
  LcFont* regularFont = font;
  LcFont* boldFont = [LcFont fontWithColor:regularFont.color
                                fontWeight:LC_FONT_WEIGHT_BOLD
                               andFontSize:regularFont.size];
  return [self attributedStringWithBoldTagString:boldTagString boldFont:boldFont regularFont:regularFont];
}

+ (NSMutableAttributedString*)attributedStringWithBoldTagString:(NSString*)boldTagString
                                                       boldFont:(LcFont*)boldFont
                                                    regularFont:(LcFont*)regularFont {
  NSMutableAttributedString* result = [[NSMutableAttributedString alloc] init];
  for (;;) {
    if ([boldTagString rangeOfString:@"<b>"].length &&
        [boldTagString rangeOfString:@"</b>"].length) {
      NSString* regularString = [boldTagString
                                 substringToIndex:[boldTagString rangeOfString:@"<b>"].location];
      [result
       appendAttributedString:[NSAttributedString
                               attributedStringWithString:regularString
                               lcFont:regularFont]];
      boldTagString = [boldTagString
                       substringFromIndex:regularString.length + @"<b>".length];
      NSString* boldSting = [boldTagString
                             substringToIndex:[boldTagString rangeOfString:@"</b>"].location];
      [result appendAttributedString:[NSAttributedString
                                      attributedStringWithString:boldSting
                                      lcFont:boldFont]];
      boldTagString =
      [boldTagString substringFromIndex:boldSting.length + @"</b>".length];
    } else {
      NSString* regularString =
      [boldTagString substringToIndex:boldTagString.length];
      [result
       appendAttributedString:[NSAttributedString
                               attributedStringWithString:regularString
                               lcFont:regularFont]];
      break;
    }
  }
  return result;

}

+ (NSMutableAttributedString*)attributedLinkTagString:(NSString*)linkTagString
                                          regularFont:(LcFont*)regularFont
                                                 urls:(NSArray<NSURL*>*)urls {
  return [self attributedLinkTagString:linkTagString
                           regularFont:regularFont
                              linkFont:regularFont.fontColor(LC_COLOR_BLUE)
                                  urls:urls];
}

+ (NSMutableAttributedString*)attributedLinkTagString:(NSString*)linkTagString
                                          regularFont:(LcFont*)regularFont
                                             linkFont:(LcFont*)linkFont
                                                 urls:(NSArray<NSURL*>*)urls {
  NSMutableAttributedString* result = [[NSMutableAttributedString alloc] init];
  NSMutableArray* mutableUrls = [NSMutableArray arrayWithArray:urls];
  NSString* startTag = @"<link>";
  NSString* endTag = @"</link>";
  for (;;) {
    if ([linkTagString rangeOfString:startTag].length &&
        [linkTagString rangeOfString:endTag].length) {
      NSString* regularString =
          [linkTagString substringToIndex:[linkTagString rangeOfString:startTag].location];
      [result appendAttributedString:[NSAttributedString attributedStringWithString:regularString
                                                                             lcFont:regularFont]];
      linkTagString = [linkTagString substringFromIndex:regularString.length + startTag.length];
      NSString* linkSting =
          [linkTagString substringToIndex:[linkTagString rangeOfString:endTag].location];

      NSMutableDictionary* linkAttributes = [[NSMutableDictionary alloc] initWithDictionary:@{
        NSFontAttributeName : linkFont.font,
        NSForegroundColorAttributeName : linkFont.color,
        NSUnderlineStyleAttributeName : @(NSUnderlineStyleSingle),
      }];
      if (mutableUrls.count > 0) {
        linkAttributes[NSLinkAttributeName] = mutableUrls.firstObject;
        [mutableUrls removeObjectAtIndex:0];
      }
      NSAttributedString* formatLinkString =
          [[NSAttributedString alloc] initWithString:linkSting attributes:linkAttributes];

      [result appendAttributedString:formatLinkString];
      linkTagString = [linkTagString substringFromIndex:linkSting.length + endTag.length];
    } else {
      NSString* regularString = [linkTagString substringToIndex:linkTagString.length];
      [result appendAttributedString:[NSAttributedString attributedStringWithString:regularString
                                                                             lcFont:regularFont]];
      break;
    }
  }
  return result;
}

- (NSAttributedString*)replaceSubString:(NSString*)subString
                                 lcFont:(LcFont*)lcFont {
  if (self.length == 0) {
    return [[NSAttributedString alloc] init];
  }
  NSUInteger length = [self length];
  NSRange range = NSMakeRange(0, length);
  NSAttributedString* attributedSubString =
  [NSAttributedString attributedStringWithString:subString lcFont:lcFont];
  NSMutableAttributedString* mutableSourceString = self.mutableCopy;

  while (range.location != NSNotFound) {
    range = [mutableSourceString.string rangeOfString:subString
                                              options:0
                                                range:range];
    if (range.location != NSNotFound) {
      [mutableSourceString
       replaceCharactersInRange:NSMakeRange(range.location,
                                            [subString length])
       withAttributedString:attributedSubString];
      range = NSMakeRange(range.location + range.length,
                          length - (range.location + range.length));
    }
  }
  return mutableSourceString;
}

- (NSAttributedString*)replaceSubStrings:(NSArray<NSString*>*)subStrings
                                  lcFont:(LcFont*)lcFont {
  if (self.length == 0) {
    return [[NSAttributedString alloc] init];
  }
  NSMutableAttributedString* mutableSourceString = self.mutableCopy;
  for (NSString* subString in subStrings) {
    if (subString.length > 0) {
      mutableSourceString =
          [mutableSourceString replaceSubString:subString lcFont:lcFont]
              .mutableCopy;
    }
  }
  return mutableSourceString;
}

- (NSAttributedString*)replaceSubString:(NSString*)subString
                               attriStr:(NSAttributedString*)replaceAttriStr {
  if (self.length == 0) {
    return [[NSAttributedString alloc] init];
  }
  if (replaceAttriStr == nil) {
    return self;
  }

  NSUInteger length = [self length];
  NSRange range = NSMakeRange(0, length);
  NSMutableAttributedString* mutableSourceString = self.mutableCopy;

  while (range.location != NSNotFound) {
    range = [mutableSourceString.string rangeOfString:subString
                                              options:0
                                                range:range];
    if (range.location != NSNotFound) {
      [mutableSourceString
       replaceCharactersInRange:NSMakeRange(range.location,
                                            [subString length])
       withAttributedString:replaceAttriStr];
      range = NSMakeRange(range.location + range.length,
                          length - (range.location + range.length));
    }
  }
  return mutableSourceString;

}

- (CGSize)sizeWithPreferredWidth:(float)width {
  CGSize retSize =
      [self boundingRectWithSize:CGSizeMake(width, MAXFLOAT)
                         options:NSStringDrawingTruncatesLastVisibleLine |
                                 NSStringDrawingUsesLineFragmentOrigin |
                                 NSStringDrawingUsesFontLeading
                         context:nil]
          .size;

  return CGSizeMake((int)retSize.width + 1, (int)retSize.height + 1);
}

- (NSAttributedString*)attributedStringWithFontSpcaing:(float)fontSpaceing {
  if (self.length == 0) {
    return [[NSAttributedString alloc] init];
  }
  NSMutableAttributedString* mutableSourceString = self.mutableCopy;
  [mutableSourceString addAttribute:NSKernAttributeName
                              value:@(fontSpaceing)
                              range:NSMakeRange(0, self.length)];
  return mutableSourceString;
}

- (NSAttributedString*)attributedStringWithLineSpacing:(float)lineSpacing {
  return [self setParagraphKey:@"lineSpacing" value:lineSpacing];
}

- (NSAttributedString*)attributedStringWithParagraphSpacing:
    (float)paragraphSpacing {
  return [self setParagraphKey:@"paragraphSpacing" value:paragraphSpacing];
}

- (NSAttributedString*)setParagraphKey:(NSString*)key value:(float)value {
  LC_CHECK_TRUE(value >= 0);
  if (self.length == 0) {
    return [[NSAttributedString alloc] init];
  }
  NSMutableAttributedString* mutableSourceString = self.mutableCopy;
  NSMutableParagraphStyle* paragraphStyle =
      [[NSMutableParagraphStyle alloc] init];
  [paragraphStyle setValue:@(value) forKey:key];
  [mutableSourceString addAttribute:NSParagraphStyleAttributeName
                              value:paragraphStyle
                              range:NSMakeRange(0, self.length)];
  return mutableSourceString;
}

@end
